package com.sansecy.customview.view.paystatus;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * 项目名称：CustomView
 * 类 名 称：PaySuccessView
 * 类 描 述：支付失败的视图
 * 创建时间：2019-11-08 10:31
 * 创 建 人：sansecy
 */
public class PayFailedView extends View {

    private Paint mPaint;
    private int mRadius;
    private Path mDstPath;
    private float mCurAnimValue;
    private PathMeasure mPathMeasure;
    private int mW;
    private int mH;
    private int mStrokeWidth = 12;
    private Path mCirclePath;
    private ValueAnimator mValueAnimator;

    public PayFailedView(Context context) {
        this(context, null);
    }

    public PayFailedView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mStrokeWidth);
        mPaint.setColor(Color.BLACK);
        mPaint.setAntiAlias(true);
        mPaint.setPathEffect(new CornerPathEffect(5));
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mDstPath = new Path();
        mCirclePath = new Path();
        mPathMeasure = new PathMeasure();

        initAnimation();
        startAnimationIfNeed();
    }

    public void setStrokeWidth(int strokeWidth) {
        mStrokeWidth = strokeWidth;
        mPaint.setStrokeWidth(mStrokeWidth);
    }

    public void startAnimationIfNeed() {
        if (mValueAnimator != null && getVisibility() == VISIBLE) {
            mValueAnimator.start();
        }
    }

    public void initAnimation() {
        mValueAnimator = ValueAnimator.ofFloat(0, 3);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurAnimValue = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        mValueAnimator.setDuration(1500);
    }

    public void addAnimatorListener(Animator.AnimatorListener animatorListener) {
        if (mValueAnimator == null) {
            initAnimation();
        }
        mValueAnimator.addListener(animatorListener);
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (visibility == VISIBLE) {
            if (mValueAnimator != null) {
                mValueAnimator.start();
            }
        } else {
            if (mValueAnimator != null && mValueAnimator.isRunning()) {
                mValueAnimator.cancel();
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = measureDimension(200, widthMeasureSpec);
        int height = measureDimension(200, heightMeasureSpec);
        setMeasuredDimension(width, height);
        mRadius = Math.min(width, height) / 2 - mStrokeWidth;
        int centerY = 0;
        int centerX = 0;
        mCirclePath.addCircle(centerX, centerY, mRadius, Path.Direction.CW);
        //每调用一次moveTo都是另一个形状了
        //左上往右下
        mCirclePath.moveTo(centerX - mRadius / 2, centerY - mRadius / 2);
        mCirclePath.lineTo(centerX + mRadius / 2, centerY + mRadius / 2);
        //右上往坐下
        mCirclePath.moveTo(centerX + mRadius / 2, centerY - mRadius / 2);
        mCirclePath.lineTo(centerX - mRadius / 2, centerY + mRadius / 2);
        mPathMeasure.setPath(mCirclePath, false);
    }

    public int measureDimension(int defaultSize, int measureSpec) {
        int result;

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = defaultSize;   //UNSPECIFIED
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    public void setRadius(int radius) {
        mRadius = radius;
    }

    public void setColor(int color) {
        mPaint.setColor(color);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mW = w;
        mH = h;
    }

    private int mCurrentStage; //当前动画阶段

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.translate(mW / 2, mH / 2);
        //有些机器上会出现第一帧显示中心点的问题，不绘制就好了
        if (mCurAnimValue < 0.01) {
            return;
        }
        if (mCurAnimValue <= 1) {
            mCurrentStage = 0;
            float stop = mPathMeasure.getLength() * mCurAnimValue;
            mPathMeasure.getSegment(0, stop, mDstPath, true);
        } else if (mCurAnimValue <= 2) {
            if (mCurrentStage == 0) {
                mCurrentStage = 1;
                mPathMeasure.getSegment(0, mPathMeasure.getLength(), mDstPath, true);
                mPathMeasure.nextContour();
            }
            float length = mPathMeasure.getLength();
            float stop = length * (mCurAnimValue - mCurrentStage);
            mPathMeasure.getSegment(0, stop, mDstPath, true);
        } else {
            if (mCurrentStage == 1) {
                mCurrentStage = 2;
                mPathMeasure.getSegment(0, mPathMeasure.getLength(), mDstPath, true);
                mPathMeasure.nextContour();
            }
            float v = mCurAnimValue - mCurrentStage;
            float stop = mPathMeasure.getLength() * v;
            mPathMeasure.getSegment(0, stop, mDstPath, true);
        }
        canvas.drawPath(mDstPath, mPaint);

    }
}
